package top.archiesean.common.core.exception;

import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.server.ServerWebExchange;
import top.archiesean.common.core.domain.R;
import top.archiesean.common.core.enums.RespStatus;

import java.util.List;

/**
 * @author ArchieSean
 * @description 全局异常处理
 * @date 2024-01-01 00:31
 */
@Slf4j
@ResponseBody
@ControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 拦截接口入参校验异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R<Object> methodArgumentNotValidException(HttpServletResponse response,
                                                     MethodArgumentNotValidException ex) {
        List<String> errors = ex.getBindingResult()
                .getAllErrors()
                .stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .toList();
        log.error("[入参校验异常]：------------>{}", ex.getMessage(), ex);
        response.setStatus(HttpStatus.OK.value());
        return R.fail(errors.toString());
    }

    /**
     * 业务异常 可以 抛出给前端
     *
     * @param response 响应
     * @param ex       捕获的异常信息
     * @return 响应数据
     */
    @ExceptionHandler(GlobalException.class)
    public R<Object> globalExceptionHandler(HttpServletResponse response, GlobalException ex) {
        log.error("[业务异常]：------->{}", ex.getMessage(), ex);
        response.setStatus(HttpStatus.OK.value());
        return R.fail(ex.getCode(), ex.getMessage());
    }


    /**
     * 系统异常 ，错误信息不能抛给前台， 做日志输出，抛出统一异常信息 fail
     *
     * @param exchange 响应
     * @param ex       捕获的异常信息
     * @return 响应数据
     */
    @ExceptionHandler(Exception.class)
    public R<Object> otherExceptionHandler(ServerWebExchange exchange, Exception ex) {
        exchange.getResponse().setStatusCode(HttpStatus.OK);
        log.error("[系统异常]：------->{}", ex.getMessage(), ex);
        return R.fail(RespStatus.FAIL);
    }
}
